home *** CD-ROM | disk | FTP | other *** search
/ Aminet 45 / Aminet 45 (2001)(GTI - Schatztruhe)[!][Oct 2001].iso / Aminet / dev / e / yaec.lha / examples / ShowHunk.e < prev    next >
Text File  |  2001-08-12  |  25KB  |  868 lines

  1. /* simple hunk-dump program with 680x0 disassembler for code hunks */
  2.  
  3. /*
  4.    WARNING: hunk_reloc32_short and hunk_relative_reloc hunks have not been
  5.    tested. If you find a file with this type of hunk, and this program
  6.    doesn't work with it, *PLEASE* contact the program authors so fixes may
  7.    be made.
  8. */
  9.  
  10. /* bugs left:
  11.    - link disasms wrong
  12.    - bset should give <illegal ea> with bit > 31
  13. */
  14.  
  15. -> YAEC1.9 : output to t:temp measured to be 11 times faster !!!
  16. -> thanks to custom stringformatting.
  17.  
  18. OPT OSVERSION=37
  19.  
  20. ENUM HUNK_UNIT=$3E7, HUNK_NAME, HUNK_CODE, HUNK_DATA, HUNK_BSS, HUNK_RELOC32,
  21.      HUNK_RELOC16, HUNK_RELOC8, HUNK_EXT, HUNK_SYMBOL, HUNK_DEBUG,
  22.      HUNK_END, HUNK_HEADER, HUNK_OVERLAY=$3F5, HUNK_BREAK, HUNK_DRELOC32,
  23.      HUNK_DRELOC16, HUNK_DRELOC8, HUNK_LIB, HUNK_INDEX, HUNK_RELOC32_S,
  24.      HUNK_REL_RELOC32
  25.  
  26. ENUM EXT_SYM=0, EXT_DEF, EXT_ABS, EXT_RES, EXT_NEWCOMMON, EXT_REF32=129,
  27.      EXT_COMMON, EXT_REF16, EXT_REF8, EXT_DREF32, EXT_DREF16, EXT_DREF8
  28.  
  29. ENUM ER_NONE,ER_FILE,ER_MEM,ER_USAGE,ER_HUNKID,ER_BREAK,ER_FILETYPE
  30.  
  31. DEF flen,o:PTR TO LONG,mem,handle=NIL,hunkid,noreloc=TRUE,hunknr=-1,f=TRUE
  32. DEF pc:PTR TO INT,hibyte,eleven2nine,eight,seven2six,five2three,two2zero,isize
  33. DEF tmp,fname[256]:STRING,disasm
  34.  
  35. PROC main() HANDLE
  36.   DEF options:PTR TO LONG,rdargs
  37.  
  38.   options:=[0,0]
  39.   IF rdargs:=ReadArgs('NAME/A,DISASM/S',options,NIL)
  40.     IF options[0] THEN StrCopy(fname,options[0])
  41.     disasm:=options[1]
  42.     FreeArgs(rdargs)
  43.   ELSE
  44.     error(ER_USAGE)
  45.   ENDIF
  46.  
  47.   PutStr('ShowHunk v2.0 Copyright (c) 1993 Jim Cooper\n')
  48.   PutStr(' Original ShowHunk v0.1 (c) 1992 $#%!\n\n')
  49.  
  50.   flen:=FileLength(fname)
  51.   handle:=Open(fname,OLDFILE)
  52.   IF (flen<1) OR (handle=NIL)
  53.     error(ER_FILE)
  54.   ELSE
  55.     mem:=New(flen)
  56.     IF mem=NIL
  57.       error(ER_MEM)
  58.     ELSE
  59.       IF Read(handle,mem,flen)<>flen THEN error(ER_FILE) ELSE process()
  60.     ENDIF
  61.   ENDIF
  62.   error(ER_NONE)
  63. EXCEPT
  64.    IF exception <> 0 THEN PrintF('unknown exception! : \d\n',exception)
  65. ENDPROC
  66.  
  67. PROC process()
  68.   DEF end,type
  69.  
  70.   o:=mem
  71.   end:=o+flen
  72.   IF (o[]<>HUNK_HEADER) AND (o[]<>HUNK_UNIT) AND (o[]<>HUNK_LIB) THEN error(ER_FILETYPE)
  73.   PrintF('Hunk layout of file \q\s\q (\d bytes)\n\n',fname,flen)
  74.   WHILE o<end
  75.     IF CtrlC() THEN error(ER_BREAK)
  76.     type:=Int(o); hunkid:=Int(o+2); o:=o+4
  77.     IF (hunkid<>HUNK_UNIT) AND (hunkid<>HUNK_HEADER) AND (hunkid<>HUNK_BREAK) AND (hunkid<>HUNK_LIB) AND (hunkid<>HUNK_INDEX)
  78.       IF f
  79.         PrintF('HUNK \d',hunknr)
  80.         hunknr++
  81.       ENDIF
  82.       f:=FALSE
  83.     ENDIF
  84.     IF type
  85.       IF type=$4000
  86.         PutStr('\t** hunk forced to CHIP-mem\n')
  87.       ELSE
  88.         PrintF('\t** type: \d\n',type)
  89.       ENDIF
  90.     ENDIF
  91.     SELECT hunkid
  92.       CASE HUNK_UNIT;        PutStr('\thunk_unit: '); name()
  93.       CASE HUNK_NAME;        PutStr('\thunk_name: '); name()
  94.       CASE HUNK_CODE;
  95.         PutStr('\thunk_code')
  96.         IF disasm
  97.           PutStr('\n'); code()
  98.         ELSE
  99.           PrintF(': \d bytes\n', skip())
  100.         ENDIF
  101.       CASE HUNK_DATA;        PrintF('\thunk_data: \d bytes\n',skip())
  102.       CASE HUNK_BSS;         PrintF('\thunk_bss: \d bytes\n',Mul(o[]++,4))
  103.       CASE HUNK_RELOC32;     PutStr('\thunk_reloc32\n'); reloc(4)
  104.       CASE HUNK_RELOC16;     PutStr('\thunk_reloc16\n'); reloc(4)
  105.       CASE HUNK_RELOC8;      PutStr('\thunk_reloc8\n'); reloc(4)
  106.       CASE HUNK_EXT;         PutStr('\thunk_ext\n'); symbol()
  107.       CASE HUNK_SYMBOL;      PutStr('\thunk_symbol\n'); symbol()
  108.       CASE HUNK_DEBUG;       PrintF('\thunk_debug: \d bytes\n',skip())
  109.       CASE HUNK_END;         f:=TRUE
  110.       CASE HUNK_HEADER;      PutStr('\thunk_header\n'); head()
  111.       CASE HUNK_OVERLAY;     PutStr('\thunk_overlay\n'); overlay()
  112.       CASE HUNK_BREAK;       PutStr('\thunk_break\n'); hunknr:=1; f:=TRUE
  113.       CASE HUNK_DRELOC32;    PutStr('\thunk_data-reloc32\n'); reloc(4)
  114.       CASE HUNK_DRELOC16;    PutStr('\thunk_data-reloc16\n'); reloc(4)
  115.       CASE HUNK_DRELOC8;     PutStr('\thunk_data-reloc8\n'); reloc(4)
  116.       CASE HUNK_LIB;         PrintF('\tlibrary_hunk: \d bytes\n',Mul(o[]++,4)); hunknr:=0
  117.       CASE HUNK_INDEX;       PrintF('\tlibrary_index: \d bytes\n\n',skip())
  118.       CASE HUNK_RELOC32_S;   PutStr('\thunk_reloc32_short\n'); reloc(2);
  119.       CASE HUNK_REL_RELOC32; PutStr('\thunk_relative_reloc32\n'); reloc(4);
  120.       DEFAULT
  121.         error(ER_HUNKID)
  122.     ENDSELECT
  123.   ENDWHILE
  124.   PutStr(IF noreloc THEN '\nPosition independant code!\n' ELSE '\n')
  125. ENDPROC
  126.  
  127. PROC overlay()
  128.   DEF m,ts
  129.   ts:=o[]++
  130.   PrintF('\t  tablesize = \d\n',ts)
  131.   m:=o[]++-2
  132.   PrintF('\t  max. level overlay tree uses = \d\n',m)
  133.   o:=ts*4+o
  134.   hunknr:=1; f:=TRUE
  135. ENDPROC
  136.  
  137. PROC symbol()
  138.   DEF t,l,s,c,r
  139.   t:=Char(o); l:=Int(o+2); o:=o+4
  140.   WHILE l
  141.     IF CtrlC() THEN error(ER_BREAK)
  142.     IF t<EXT_NEWCOMMON                  /* sym def */
  143.       s:=o; o:=l*4+o; c:=o[]++; PutChar(o-4,0)
  144.       PrintF('\t  \s = $\h\n',s,c)
  145.     ELSEIF (t=EXT_COMMON) OR (t=EXT_NEWCOMMON)  /* common ref */
  146.       s:=o; o:=l*4+o; c:=o[]++; PutChar(o-4,0); r:=o[]++
  147.       PrintF('\t  \s (\d ref\s) commonsize = \d\n',s,r,
  148.              IF r=1 THEN '' ELSE 's',c)
  149.       o:=r*4+o
  150.     ELSE                                /* sym ref */
  151.       s:=o; o:=l*4+o; r:=o[]++; PutChar(o-4,0)
  152.       PrintF('\t  \s (\d ref\s)\n',s,r,IF r=1 THEN '' ELSE 's')
  153.       o:=r*4+o
  154.     ENDIF
  155.     t:=Char(o); l:=Int(o+2); o:=o+4
  156.   ENDWHILE
  157. ENDPROC
  158.  
  159. PROC head()
  160.   DEF a,b
  161.   a:=0
  162.   b:=o[a]++
  163.   WHILE b
  164.     PrintF('\t  libname: \s\n',o)
  165.     a:=a+b
  166.     b:=o[a]++
  167.   ENDWHILE
  168.   b:=o[]++
  169.   hunknr:=o[]++
  170.   a:=o[]++-hunknr+1
  171.   PrintF('\t  #of hunks: \d\n',a)
  172.   o:=a*4+o
  173. ENDPROC
  174.  
  175. PROC reloc(size)
  176.   DEF a
  177.   noreloc:=FALSE
  178.   a:=o[]++
  179.   WHILE a
  180.     IF CtrlC() THEN error(ER_BREAK)
  181.     PrintF('\t  \d reloc entr\s for hunk #\d\n',a,
  182.            IF a=1 THEN 'y' ELSE 'ies',o[]++)
  183.     o:=a*size+o
  184.     a:=o[]++
  185.   ENDWHILE
  186. ENDPROC
  187.  
  188. PROC name()
  189.   DEF a
  190.   a:=o[]++
  191.   PrintF('\s\n',o)
  192.   o:=a*4+o
  193. ENDPROC
  194.  
  195. PROC skip()
  196.   DEF a
  197.   a:=Mul(o[]++,4)
  198.   o:=o+a
  199. ENDPROC a
  200.  
  201. PROC error(nr)
  202.   IF handle THEN Close(handle)
  203.   PutStr('\n')
  204.   SELECT nr
  205.     CASE ER_FILE;     PrintF('Could not read file \q\s\q !\n',fname)
  206.     CASE ER_MEM;      PutStr('No memory for hunks!\n')
  207.     CASE ER_USAGE;    PutStr('USAGE: ShowHunk <exe/objfile>\n')
  208.     CASE ER_HUNKID;   PrintF('Illegal hunk id: $\h !\n',hunkid)
  209.     CASE ER_BREAK;    PutStr('** BREAK: ShowHunk\n')
  210.     CASE ER_FILETYPE; PutStr('Not an executable or object file.\n')
  211.   ENDSELECT
  212.   Raise(0) ->CleanUp()
  213. ENDPROC
  214.  
  215. PROC illegal()
  216.   PrintF('<illegal opcode: $\h>\n',pc[])
  217. ENDPROC
  218.  
  219. PROC opsize(bit) IS ListItem(["b","w","l","?"],bit)
  220.  
  221. PROC bitsize(bit) IS IF bit THEN "l" ELSE "w"
  222.  
  223. PROC immed(val)
  224.   PrintF(IF val < 16 THEN '\d' ELSE '$\h',val)
  225. ENDPROC
  226.  
  227. PROC ccode(val,b) IS ListItem([IF b THEN 'ra' ELSE 't',
  228.   IF b THEN 'sr' ELSE 'f','hi','ls','cc','cs','ne','eq','vc',
  229.   'vs','pl','mi','ge','lt','gt','le','??'],val)
  230.  
  231. PROC ea(mode,reg,sd)
  232.   IF mode < 5 THEN
  233.     PrintF(ListItem(['d\d','a\d','(a\d)','(a\d)+','-(a\d)'],mode),reg)
  234.   SELECT mode
  235.     CASE 5;
  236.        PutStr('(')
  237.        immed(pc[1]++)
  238.        PrintF(',a\d)',reg)
  239.     CASE 6;
  240.       tmp:=pc[1]++
  241.       PutStr('(')
  242.       immed(tmp AND $f)
  243.       PrintF(',a\d,\s\d\s',reg,
  244.                            IF tmp AND $8000 THEN 'a' ELSE 'd',
  245.                            (Shr(tmp,12) AND 7),
  246.                            IF tmp AND $800 THEN '.L)' ELSE '.W)')
  247.     CASE 7;
  248.       SELECT reg
  249.         CASE 0;  PrintF('(\d).W',pc[1]++)
  250.         CASE 1;  immed(Long(pc+2)); pc:=pc+4      /* bug! was: immed(Int(pc++)) */
  251.         CASE 2;
  252.           PutStr('(')
  253.           immed(pc[1]++)
  254.           PutStr(',PC)')
  255.         CASE 3;
  256.           tmp:=pc[1]++
  257.           PutStr('(')
  258.           immed(tmp AND $f)
  259.           PrintF(',PC,\c\d\s',IF tmp AND $8000 THEN "a" ELSE "d",
  260.                               (Shr(tmp,12) AND 7),
  261.                               IF tmp AND $800 THEN '.L)' ELSE '.W)')
  262.         CASE 4;
  263.           IF sd
  264.             PutStr('#')
  265.             immed(IF isize=2 THEN pc[1] ELSE Long(pc+2))
  266.             pc:=pc+isize
  267.           ELSE
  268.             PutStr('SR')
  269.           ENDIF
  270.         DEFAULT;
  271.           PutStr('<unknown ea!>')
  272.       ENDSELECT
  273.   ENDSELECT
  274. ENDPROC
  275.  
  276. PROC movemregs(val,predec)
  277.   DEF index,first=1,regs:PTR TO LONG
  278.  
  279.   regs:=['d0','d1','d2','d3','d4','d5','d6','d7',
  280.          'a0','a1','a2','a3','a4','a5','a6','a7']
  281.  
  282.   IF predec
  283.     FOR index:=15 TO 0 STEP -1
  284.       IF val AND Shl(1,index)
  285.         IF first = 0 THEN PutStr('/')
  286.         PutStr(regs[15-index])
  287.         first:=0
  288.       ENDIF
  289.     ENDFOR
  290.   ELSE
  291.     FOR index:=0 TO 15 STEP 1
  292.       IF val AND Shl(1,index)
  293.         IF first = 0 THEN PutStr('/')
  294.         PutStr(regs[index])
  295.         first:=0
  296.       ENDIF
  297.     ENDFOR
  298.   ENDIF
  299. ENDPROC
  300.  
  301. PROC code0000()
  302.   DEF c,tmp2
  303.  
  304.   IF (eleven2nine = 7) OR (seven2six = 3)
  305.     IF (eleven2nine = 7) AND (eight = 0)
  306.       tmp:=pc[1]++
  307.       PrintF('moves.\c\t',opsize(seven2six))
  308.       IF Shr(tmp,11) AND 1
  309.         ea(five2three,two2zero,1)
  310.         PrintF(',\c\d\n',IF tmp AND $8000 THEN "a" ELSE "d",Shr(tmp,12) AND 7)
  311.       ELSE
  312.         PrintF('\c\d,',IF tmp AND $8000 THEN "a" ELSE "d",Shr(tmp,12) AND 7)
  313.         ea(five2three,two2zero,0)
  314.         PutStr('\n')
  315.       ENDIF
  316.     ELSEIF (eight = 0) AND (seven2six = 3)
  317.       tmp:=pc[1]++
  318.       IF (five2three = 7) AND (two2zero = 4)
  319.         tmp2:=pc[1]++
  320.         PrintF('cas2\td\d:d\d,d\d:d\d,\c\d:\c\d\n',
  321.                (tmp AND 7), (tmp2 AND 7),
  322.                (Shr(tmp,6) AND 7), (Shr(tmp2,6) AND 7),
  323.                IF tmp AND $8000 THEN "a" ELSE "d", (Shr(tmp,12) AND 7),
  324.                IF tmp2 AND $8000 THEN "a" ELSE "d", (Shr(tmp2,12) AND 7))
  325.       ELSE
  326.         PrintF('cas\td\d,d\d,',tmp AND 7, Shr(tmp,6) AND 7)
  327.         ea(five2three,two2zero,0)
  328.         PutStr('\n')
  329.       ENDIF
  330.     ELSE
  331.       illegal()
  332.     ENDIF
  333.   ELSE
  334.     IF five2three = 1
  335.       PrintF('movep.\c\t',bitsize(seven2six AND 1))
  336.       IF seven2six AND 2
  337.         PrintF('d\d,\d(a\d)\n',eleven2nine,pc[1]++,two2zero)
  338.       ELSE
  339.         PrintF('\d(a\d),d\d\n',pc[1]++,two2zero,eleven2nine)
  340.       ENDIF
  341.     ELSEIF (eight = 1) OR ((((eleven2nine AND 3) = 0) AND (eight = 0)))
  342.       PrintF(ListItem(['btst\t','bchg\t','bclr\t','bset\t'],seven2six))
  343.       IF eight = 1
  344.         PrintF('d\d,',eleven2nine)
  345.       ELSE
  346.         PrintF('#\d,',pc[1]++)
  347.       ENDIF
  348.       ea(five2three,two2zero,0)
  349.       PutStr('\n')
  350.     ELSE
  351.       IF seven2six = 3
  352.         tmp:=pc[1]++
  353.         PrintF('\s.\c\t',IF Shr(tmp,11) AND 1 THEN 'chk2' ELSE 'cmp2',opsize(eleven2nine))
  354.         ea(five2three,two2zero,1)
  355.         PrintF(',\c\d\n',IF tmp AND $8000 THEN "d" ELSE "a",Shr(tmp,12) AND 3)
  356.       ELSE
  357.         c:=ListItem(['ori.','andi.','subi.','addi.',0,'eori.','cmpi.',0],eleven2nine)
  358.         IF c THEN PutStr(c) ELSE illegal()
  359.         PrintF('\c\t#',opsize(seven2six))
  360.         immed(IF seven2six < 2 THEN pc[1]++ ELSE Int(pc++))
  361.         PutStr(',')
  362.         ea(five2three,two2zero,0)
  363.         PutStr('\n')
  364.       ENDIF
  365.     ENDIF
  366.   ENDIF
  367. ENDPROC
  368.  
  369. PROC code0100()
  370.   DEF subfield,bitseven,bitsix,curcode
  371.  
  372.   bitseven:=Shr(seven2six,1)
  373.   bitsix:=seven2six AND 1
  374.  
  375.   IF pc[] = $4afa
  376.     PutStr('bgnd\n')
  377.   ELSE
  378.     IF eight = 1
  379.       IF bitsix = 1
  380.         PutStr('lea\t')
  381.         ea(five2three,two2zero,1)
  382.         PrintF(',a\d\n',eleven2nine)
  383.       ELSE
  384.         PutStr('chk\t')
  385.         ea(five2three,two2zero,0)
  386.         PrintF(',d\d\n',eleven2nine)
  387.       ENDIF
  388.     ELSE
  389.       subfield:=Shl(eleven2nine,1)+eight
  390.  
  391.       SELECT subfield
  392.         CASE 0;
  393.           IF seven2six = 3
  394.             PutStr('move.w\t')
  395.             ea(five2three,two2zero,1)
  396.             PutStr(',sr\n')
  397.           ELSE
  398.             PrintF('negx.\c\t',opsize(seven2six))
  399.             ea(five2three,two2zero,0)
  400.             PutStr('\n')
  401.           ENDIF
  402.         CASE 1;
  403.           IF seven2six = 3
  404.             PutStr('move.w\tccr,')
  405.             ea(five2three,two2zero,0)
  406.             PutStr('\n')
  407.           ELSE
  408.             illegal()
  409.           ENDIF
  410.         CASE 2;
  411.           PrintF('clr.\c\t',opsize(seven2six))
  412.           ea(five2three,two2zero,0)
  413.           PutStr('\n')
  414.         CASE 4;
  415.           IF seven2six = 3
  416.             PutStr('move.w\t')
  417.             ea(five2three,two2zero,1)
  418.             PutStr(',ccr\n')
  419.           ELSE
  420.             PrintF('neg.\c\t',opsize(seven2six))
  421.             ea(five2three,two2zero,0)
  422.             PutStr('\n')
  423.           ENDIF
  424.         CASE 6;
  425.           IF seven2six = 3
  426.             PutStr('move.w\tsr,')
  427.             ea(five2three,two2zero,0)
  428.             PutStr('\n')
  429.           ELSE
  430.             PrintF('not.\c\t',opsize(seven2six))
  431.             ea(five2three,two2zero,0)
  432.             PutStr('\n')
  433.           ENDIF
  434.         CASE 8;
  435.           IF seven2six = 0
  436.             IF five2three = 1
  437.               PrintF('link.l\ta\d,#-$\h\n',two2zero,0-1-Int(pc++))
  438.             ELSE
  439.               PutStr('nbcd\t')
  440.               ea(five2three,two2zero,0)
  441.               PutStr('\n')
  442.             ENDIF
  443.           ELSEIF seven2six = 1
  444.             IF five2three = 0
  445.               PrintF('swap\td\d\n',two2zero)
  446.             ELSEIF five2three = 1
  447.               PrintF('bkpt\t#\d\n',two2zero)
  448.             ELSE
  449.               PutStr('pea\t')
  450.               ea(five2three,two2zero,0)
  451.               PutStr('\n')
  452.             ENDIF
  453.           ELSE
  454.             IF five2three = 0
  455.               IF (Shl(eight,2)+seven2six) = 7 THEN PrintF('extb.l\td\d\n',two2zero) ELSE PrintF('ext.\c\td\d\n',bitsize(bitsix),two2zero)
  456.             ELSE
  457.               PrintF('movem.\c\t',bitsize(bitsix))
  458.               movemregs(pc[1]++, IF five2three = 4 THEN 1 ELSE 0)
  459.               PutStr(',')
  460.               ea(five2three,two2zero,0)
  461.               PutStr('\n')
  462.             ENDIF
  463.           ENDIF
  464.         CASE 10;
  465.           IF pc[] = $4afc
  466.             PutStr('illegal\n')
  467.           ELSE
  468.             IF seven2six = 3
  469.               PutStr('tas\t')
  470.               ea(five2three,two2zero,0)
  471.               PutStr('\n')
  472.             ELSE
  473.               PrintF('tst.\c\t',opsize(seven2six))
  474.               ea(five2three,two2zero,0)
  475.               PutStr('\n')
  476.             ENDIF
  477.           ENDIF
  478.         CASE 12;
  479.           tmp:=pc[1]++
  480.  
  481.           IF (Shl(eight,2)+seven2six) < 2
  482.             IF seven2six = 1
  483.               PrintF('div\c',IF Shr(tmp,11) AND 1 THEN "s" ELSE "u")
  484.               IF ((Shr(tmp,10) AND 1) = 0) AND ((Shr(tmp,12) AND 7) <> (tmp AND 7))
  485.                 PutStr('l.l\t')
  486.                 ea(five2three,two2zero,1)
  487.                 PrintF(',d\d:d\d\n',Shr(tmp,12) AND 7,tmp AND 7)
  488.               ELSE
  489.                 PutStr('.l\t')
  490.                 ea(five2three,two2zero,1)
  491.                 PrintF(',d\d',Shr(tmp,12) AND 7)
  492.                 IF Shr(tmp,10) AND 1 THEN PrintF(':d\d',tmp AND 7)
  493.                 PutStr('\n')
  494.               ENDIF
  495.             ELSE
  496.               PrintF('mul\c.l\t',IF Shr(tmp,11) AND 1 THEN "s" ELSE "u")
  497.               ea(five2three,two2zero,1)
  498.               PrintF(',d\d',Shr(tmp,12) AND 7)
  499.               IF Shr(tmp,10) AND 1 THEN PrintF(':d\d',tmp AND 7)
  500.               PutStr('\n')
  501.             ENDIF
  502.           ELSE
  503.             PrintF('movem.\c\t',bitsize(bitsix))
  504.             ea(five2three,two2zero,0)
  505.             PutStr(',')
  506.             movemregs(tmp, IF five2three = 4 THEN 1 ELSE 0)
  507.             PutStr('\n')
  508.           ENDIF
  509.         CASE 14;
  510.           curcode:=pc[]
  511.  
  512.           SELECT curcode
  513.             CASE $4e70;
  514.               PutStr('reset\n')
  515.             CASE $4e71;
  516.               PutStr('nop\n')
  517.             CASE $4e72;
  518.               PutStr('stop\n')
  519.             CASE $4e73;
  520.               PutStr('rte\n')
  521.             CASE $4e74;
  522.               PrintF('rtd\t#\d\n',(Shl(pc[1]<32767+1,16)-pc[1]++))
  523.             CASE $4e75;
  524.               PutStr('rts\n')
  525.             CASE $4e76;
  526.               PutStr('trapv\n')
  527.             CASE $4e77;
  528.               PutStr('rtr\n')
  529.             DEFAULT;
  530.               IF bitseven = 1
  531.                 PutStr(IF bitsix = 1 THEN 'jmp\t' ELSE 'jsr\t')
  532.                 ea(five2three,two2zero,0)
  533.                 PutStr('\n')
  534.               ELSE
  535.                 IF bitsix = 1
  536.                   tmp:=Shr(five2three,1)
  537.  
  538.                   SELECT tmp
  539.                     CASE 0;
  540.                       PrintF('trap\t\d\n',(Shl((five2three AND 1),2)+two2zero))
  541.                     CASE 1;
  542.                       IF five2three AND 1
  543.                         PrintF('unlk\ta\d\n',two2zero)
  544.                       ELSE
  545.                         PrintF('link.w\ta\d,#-$\h\n',two2zero,65536-pc[1]); pc++
  546.  
  547.                       ENDIF
  548.                     CASE 2;
  549.                       PrintF(IF five2three AND 1 THEN 'move\tusp,a\d\n' ELSE 'move\ta\d,usp\n',two2zero)
  550.                     CASE 3;
  551.                       PrintF('rtm\t\c\d\n',IF five2three AND 1 THEN "a" ELSE "d",two2zero)
  552.                   ENDSELECT
  553.                 ELSE
  554.                   illegal()
  555.                 ENDIF
  556.               ENDIF
  557.           ENDSELECT
  558.         DEFAULT; illegal()
  559.       ENDSELECT
  560.     ENDIF
  561.   ENDIF
  562. ENDPROC
  563.  
  564. PROC code0101()
  565.   IF seven2six < 3
  566.     PutStr(IF eight = 1 THEN 'subq.' ELSE 'addq.')
  567.     PrintF('\c\t#\d,',opsize(seven2six),eleven2nine)
  568.     ea(five2three,two2zero,0)
  569.     PutStr('\n')
  570.   ELSE
  571.     IF five2three = 1
  572.       PrintF('db\s\td\d,\z\h[8]\n',
  573.              ccode((Shl(eleven2nine,1)+eight),0),
  574.              two2zero,
  575.              pc-o-2-(Shl(pc[1]<32767+1,16)-pc[1]))
  576.       pc++
  577.     ELSEIF five2three = 7
  578.       PrintF('trap\s',ccode(Shl(eleven2nine,1)+eight,0))
  579.       IF two2zero < 4
  580.         IF two2zero AND 1 THEN PrintF('.w\t#\d',pc[1]++) ELSE PrintF('.l\t#\d',Int(pc++))
  581.       ENDIF
  582.       PutStr('\n')
  583.     ELSE
  584.       PrintF('s\s\t',ccode(Shl(eleven2nine,1)+eight,0))
  585.       ea(five2three,two2zero,0)
  586.       PutStr('\n')
  587.     ENDIF
  588.   ENDIF
  589. ENDPROC
  590.  
  591. PROC code0110()
  592.   DEF tmp2,ctl:PTR TO LONG
  593.  
  594.   IF (pc[] AND $fffe) = $4e7a
  595.     tmp:=pc[1]++
  596.     tmp2:= tmp AND $fff
  597.     IF tmp2 > 7
  598.       ctl:=ListItem(['usp','vbr','caar','msp','isp','mmusr','urp','srp'],tmp2 - $800)
  599.     ELSE
  600.       ctl:=ListItem(['sfc','dfc','cacr','tc','itt0','itt1','dtt0','dtt1'],tmp2)
  601.     ENDIF
  602.     IF ctl
  603.       PutStr('movec\t')
  604.       IF pc[-1] AND 1
  605.         PrintF('\s,\c\d\n',ctl,IF tmp AND $8000 THEN "a" ELSE "d",Shr(tmp,12) AND 7)
  606.       ELSE
  607.         PrintF('\c\d,\s\n',IF tmp AND $8000 THEN "a" ELSE "d",Shr(tmp,12) AND 7,ctl)
  608.       ENDIF
  609.     ELSE
  610.       illegal()
  611.     ENDIF
  612.   ELSE
  613.     PrintF('b\s',ccode((Shl(eleven2nine,1)+eight),1))
  614.     tmp:=Char(pc+1)
  615.     IF tmp = 0
  616.       PrintF('.w\tL\z\h[8]\n',pc-o-2-(Shl(pc[1]<32767+1,16)-pc[1]))
  617.       pc++
  618.     ELSE
  619.       PrintF('.b\tL\z\h[8]\n',pc-o-2-(Shl(tmp<127+1,8)-tmp))
  620.     ENDIF
  621.   ENDIF
  622. ENDPROC
  623.  
  624. PROC code1000()
  625.   IF Shr(pc[],4) AND (%11111 = %10100)   /* bug!: was  Shr(five2three,1) = 0 */
  626.     IF eight
  627.       IF seven2six
  628.         SELECT seven2six
  629.           CASE 1;  PutStr('pack\t')
  630.           CASE 2;  PutStr('unpk\t')
  631.           DEFAULT; illegal()
  632.         ENDSELECT
  633.         PrintF(IF five2three AND 1 THEN '-(a\d),-(a\d),#\d\n' ELSE 'd\d,d\d,#\d\n',two2zero,eleven2nine,pc[1]++)
  634.       ELSE
  635.         PrintF(IF five2three AND 1 THEN 'sbcd\t-(a\d),-(a\d)\n' ELSE 'sbcd\td\d,-d\d\n',two2zero,eleven2nine)
  636.       ENDIF
  637.     ELSE
  638.       illegal()
  639.     ENDIF
  640.   ELSE
  641.     IF seven2six = 3
  642.       PutStr(IF eight = 1 THEN 'divs\t' ELSE 'divu\t')
  643.       ea(five2three,two2zero,1)
  644.       PrintF(',d\d\n',eleven2nine)
  645.     ELSE
  646.       PrintF('or.\c\t',opsize(seven2six))
  647.       IF eight = 1
  648.         PrintF('d\d,',eleven2nine)
  649.         ea(five2three,two2zero,0)
  650.       ELSE
  651.         ea(five2three,two2zero,1)
  652.         PrintF(',d\d',eleven2nine)
  653.       ENDIF
  654.       PutStr('\n')
  655.     ENDIF
  656.   ENDIF
  657. ENDPROC
  658.  
  659. PROC code1001()
  660.   IF seven2six = 3
  661.     PrintF('suba.\c\t',bitsize(eight))
  662.     ea(five2three,two2zero,1)
  663.     PrintF(',a\d\n',eleven2nine)
  664.   ELSE
  665.     IF (Shr(five2three,1) = 0) AND (eight = 1)
  666.       PrintF('subx.\c\t',opsize(seven2six))
  667.       PrintF(IF five2three AND 1 THEN '-(a\d),-(a\d)\n' ELSE 'd\d,d\d\n',two2zero,eleven2nine)
  668.     ELSE
  669.       PrintF('sub.\c\t',opsize(seven2six))
  670.       IF eight = 1
  671.         PrintF('d\d,',eleven2nine)
  672.         ea(five2three,two2zero,0)
  673.         PutStr('\n')
  674.       ELSE
  675.         ea(five2three,two2zero,1)
  676.         PrintF(',d\d\n',eleven2nine)
  677.       ENDIF
  678.     ENDIF
  679.   ENDIF
  680. ENDPROC
  681.  
  682. PROC code1011()
  683.   IF seven2six = 3
  684.     PrintF('cmpa.\c\t',bitsize(eight))
  685.     ea(five2three,two2zero,1)
  686.     PrintF(',a\d\n',eleven2nine)
  687.   ELSE
  688.     IF five2three = 1
  689.       PrintF('cmpm.\c\t(a\d)+,(a\d)+\n',opsize(seven2six),two2zero,eleven2nine)
  690.     ELSE
  691.       IF eight = 1
  692.         PrintF('eor.\c\td\d,',opsize(seven2six),eleven2nine)
  693.         ea(five2three,two2zero,0)
  694.         PutStr('\n')
  695.       ELSE
  696.         PrintF('cmp.\c\t',opsize(seven2six))
  697.         ea(five2three,two2zero,1)
  698.         PrintF(',d\d\n',eleven2nine)
  699.       ENDIF
  700.     ENDIF
  701.   ENDIF
  702. ENDPROC
  703.  
  704. PROC code1100()
  705.   IF seven2six = 3
  706.     PutStr(IF eight = 1 THEN 'mulu.w\t' ELSE 'muls.w\t')
  707.     ea(five2three,two2zero,1)
  708.     PrintF(',d\d\n',eleven2nine)
  709.   ELSE
  710.     IF Shr(five2three,1) <> 0
  711.       PrintF('and.\c\t',opsize(seven2six))
  712.       IF eight = 1
  713.         PrintF('d\d,',eleven2nine)
  714.         ea(five2three,two2zero,0)
  715.         PutStr('\n')
  716.       ELSE
  717.         ea(five2three,two2zero,1)
  718.         PrintF(',d\d\n',eleven2nine)
  719.       ENDIF
  720.     ELSE
  721.       IF seven2six = 0
  722.         PrintF(IF five2three AND 1 THEN 'abcd\t-(a\d),-(a\d)\n' ELSE 'abcd\td\d,d\d\n',two2zero,eleven2nine)
  723.       ELSE
  724.         PutStr('exg\t')
  725.         tmp:=Shl(seven2six,3)+five2three
  726.         IF tmp = 8
  727.           PrintF('d\d,d\d\n',two2zero,eleven2nine)
  728.         ELSEIF tmp = 9
  729.           PrintF('a\d,a\d\n',two2zero,eleven2nine)
  730.         ELSEIF tmp = 17
  731.           PrintF('a\d,d\d\n',two2zero,eleven2nine)
  732.         ELSE
  733.           illegal()
  734.         ENDIF
  735.       ENDIF
  736.     ENDIF
  737.   ENDIF
  738. ENDPROC
  739.  
  740. PROC code1101()
  741.   IF seven2six = 3
  742.     PrintF('adda.\c\t',bitsize(eight))
  743.     ea(five2three,two2zero,1)
  744.     PrintF(',a\d\n',eleven2nine)
  745.   ELSE
  746.     IF (Shr(five2three,1) = 0) AND (eight = 1)
  747.       PrintF('addx.\c\t',opsize(seven2six))
  748.       PrintF(IF five2three AND 1 THEN '-(a\d),-(a\d)\n' ELSE 'd\d,d\d\n',two2zero,eleven2nine)
  749.     ELSE
  750.       PrintF('add.\c\t',opsize(seven2six))
  751.       IF eight = 1
  752.         PrintF('d\d,',eleven2nine)
  753.         ea(five2three,two2zero,0)
  754.         PutStr('\n')
  755.       ELSE
  756.         ea(five2three,two2zero,1)
  757.         PrintF(',d\d\n',eleven2nine)
  758.       ENDIF
  759.     ENDIF
  760.   ENDIF
  761. ENDPROC
  762.  
  763. PROC code1110()
  764.   DEF subfield,tmp2
  765.  
  766.   IF seven2six = 3
  767.     tmp:=pc[1]++
  768.     tmp2:=tmp AND 31
  769.     subfield:=Shl((eleven2nine AND 3),1)+eight
  770.     PutStr(ListItem(['bftst','bfextu','bfchg','bfexts','bfclr','bfffo','bfset','bfins'],subfield))
  771.     PutStr('\t')
  772.     IF subfield = 7 THEN PrintF('d\d,',Shr(tmp,12) AND 7)
  773.     ea(five2three,two2zero,0)
  774.     PrintF(IF Shr(tmp,11) AND 1 THEN '{d\d:' ELSE '{\d:',Shr(tmp,6) AND 31)
  775.     PrintF(IF Shr(tmp,5) AND 1 THEN 'd\d}' ELSE '\d}',IF tmp2 THEN tmp2 ELSE 32)
  776.  
  777.     IF (subfield < 7) AND (subfield AND 1) THEN PrintF(',d\d',Shr(tmp,12) AND 7)
  778.  
  779.     PutStr('\n')
  780.   ELSE
  781.     PrintF('\s\c',ListItem(['as','ls','rox','ro'],IF seven2six=3 THEN eleven2nine ELSE five2three AND 3),IF eight=1 THEN "l" ELSE "r")
  782.     IF seven2six = 3
  783.       PutStr('\t')
  784.       ea(five2three,two2zero,0)
  785.       PutStr('\n')
  786.     ELSE
  787.       PrintF(IF five2three AND 4 THEN '.\c\td\d,d\d\n' ELSE '\c\t#\d,d\d\n',opsize(seven2six),eleven2nine,two2zero)
  788.     ENDIF
  789.   ENDIF
  790. ENDPROC
  791.  
  792. PROC code()
  793.   DEF number
  794.  
  795.   isize:=2
  796.   number:=Shl(o[],2)+o+4
  797.   pc:=o+4
  798.  
  799.   PutStr('\n')
  800.  
  801.   WHILE (pc < number)
  802.     hibyte:=Shr(Char(pc),4)
  803.     eleven2nine:=Shr(Char(pc),1) AND 7
  804.     eight:=Char(pc) AND 1
  805.     seven2six:=Shr(Char(pc+1),6) AND 3
  806.     five2three:=Shr(Char(pc+1),3) AND 7
  807.     two2zero:=Char(pc+1) AND 7
  808.  
  809.     IF CtrlC() THEN error(ER_BREAK)             /* essential! */
  810.  
  811.     PrintF('L\z\h[8]:',pc-o-4)                  /* for offsets */
  812.  
  813.     PutStr('\t')
  814.  
  815.     IF (hibyte > 0) AND (hibyte < 4)
  816.       PutStr(IF (eight=0) AND (seven2six=1) THEN 'movea.' ELSE 'move.')
  817.       SELECT hibyte
  818.         CASE 1; PutStr('b')
  819.         CASE 2; PutStr('l'); isize:=4
  820.         CASE 3; PutStr('w')
  821.       ENDSELECT
  822.       PutStr('\t')
  823.       ea(five2three,two2zero,1)
  824.       PutStr(',')
  825.       ea(Shl(eight,2)+seven2six,eleven2nine,0)
  826.       PutStr('\n')
  827.       isize:=2
  828.     ELSE
  829.       SELECT hibyte
  830.         CASE 0;                 /* Bit Manipulation/MOVEP/immediate */
  831.           code0000()
  832.         CASE 4;                 /* Miscellaneous */
  833.           code0100()
  834.         CASE 5;                 /* ADDQ/SUBQ/Scc/DBcc/TRAPcc */
  835.           code0101()
  836.         CASE 6;                 /* Bcc/BSR/BRA/MOVEC */
  837.           code0110()
  838.         CASE 7;                 /* MOVEQ */
  839.           PutStr('moveq\t#')
  840.           immed(Char(pc+1))
  841.           PrintF(',d\d\n',eleven2nine)
  842.         CASE 8;                 /* OR/DIV/SBCD */
  843.           code1000()
  844.         CASE 9;                 /* SUB/SUBA/SUBX */
  845.           code1001()
  846.         CASE 10;                /* (unassigned, reserved) */
  847.           illegal()
  848.         CASE 11;                /* CMP/EOR */
  849.           code1011()
  850.         CASE 12;                /* AND/MUL/ABCD/EXG */
  851.           code1100()
  852.         CASE 13;                /* ADD/ADDX */
  853.           code1101()
  854.         CASE 14;                /* Shift/Rotate/Bit Field */
  855.           code1110()
  856.         CASE 15;                /* Coprocessor Interface */
  857.           illegal()
  858.       ENDSELECT
  859.     ENDIF
  860.     pc++
  861.   ENDWHILE
  862.  
  863.   PutStr('\n')
  864.  
  865.   o:=number
  866. ENDPROC
  867.  
  868.